#include <sstream>
#include "common.h"
#include "cJSON.h"
#include <iostream>
#include "server.h"

/**
 * 将JSON解析成Message类型
 * command: exit, restart, theme
 *
 * {
 *      "name":"plugin",
 *      "command":"restart",
 *      "args":
 *      {
 *          "jsBundle":"XXXXX",
 *          "deviceType":"XXXXX"
 *      }
 * }
 */

/**
 * @brief CMessage::parseJson
 * @param json
 * @return
 */
CMessage CMessage::parseJson(const std::string& json){
    CMessage msg;
    cJSON *root = NULL;
    cJSON *name = NULL;
    cJSON *command = NULL;
    cJSON *args = NULL;
    cJSON *child = NULL;

    root = cJSON_Parse(json.data());
    if (!root) {
        return msg;
    }   
    name = cJSON_GetObjectItem(root, "name");
    if (!name) {
        return msg;
    }
    msg.name = name->valuestring;
    command = cJSON_GetObjectItem(root, "command");
    if (!command) {
        return msg;
    }
    msg.command = command->valuestring;
    args = cJSON_GetObjectItem(root, "args");
    if (!args) {
        return msg;
    }
    child = args->child;

    while(child != NULL){
        std::string key = child->string;
        std::string value = child->valuestring;
        //std::cout << "key:" << key << ",value:" << value << std::endl;
        msg.args.insert(std::make_pair(key,value));
        child = child->next;
    }

    cJSON_Delete(root);
    return std::move(msg);
}

/**
 * @brief CMessage::toString
 * @return
 */
std::string CMessage::toString() {
    cJSON * root =  cJSON_CreateObject();
    cJSON_AddItemToObject(root, "name", cJSON_CreateString(this->name.c_str()));
    cJSON_AddItemToObject(root, "command", cJSON_CreateString(this->command.c_str()));
    cJSON *args = cJSON_CreateObject();
    for(auto arg:this->args){
        cJSON_AddItemToObject(args, arg.first.c_str(), cJSON_CreateString(arg.second.c_str()));
    }
    cJSON_AddItemToObject(root, "args", args);
    std::string result = cJSON_Print(root);
    cJSON_Delete(root);
    return result;
}

PMessage PMessage::parseJson(const std::string &json) {
    PMessage msg;
    cJSON *root = NULL;
    cJSON *name = NULL;
    cJSON *command = NULL;
    cJSON *args = NULL;
    cJSON *child = NULL;

    root = cJSON_Parse(json.data());
    if (!root) {
        return msg;
    }

    name = cJSON_GetObjectItem(root, "name");
    if (!name) {
        return msg;
    }
    msg.name = name->valuestring;

    command = cJSON_GetObjectItem(root, "command");
    if (!command) {
        return msg;
    }
    msg.command = command->valuestring;

    args = cJSON_GetObjectItem(root, "args");
    if (!args) {
        return msg;
    }
    child = args->child;

    while(child != NULL){
        std::string key = child->string;
        int value = child->valueint;
        //std::cout << "key:" << key << ",value:" << value << std::endl;
        msg.args.insert(std::make_pair(key,value));
        child = child->next;
    }
    cJSON_Delete(root);

    return std::move(msg);
}

std::string PMessage::toString() {
    cJSON * root =  cJSON_CreateObject();
    cJSON_AddItemToObject(root, "name", cJSON_CreateString(this->name.c_str()));
    cJSON_AddItemToObject(root, "command", cJSON_CreateString(this->command.c_str()));
    cJSON *args = cJSON_CreateObject();
    for(auto arg:this->args){
        cJSON_AddItemToObject(args, arg.first.c_str(), cJSON_CreateNumber(arg.second));
    }
    cJSON_AddItemToObject(root, "args", args);
    std::string result = cJSON_Print(root);
    cJSON_Delete(root);
    return result;
}

/**
 * @brief ReadFileContent 读取文件
 * @param pFilePath 文件路径
 * @param mode 读取方式 文本和二进制
 * @param strContent 读取到的内容
 * @return
 */
bool ReadFileContent(const char* pFilePath, std::ios_base::openmode mode,std::string& strContent) {
    std::ostringstream buf;
    strContent.clear();
    std::ifstream infile;
    char ch;
    infile.open(pFilePath, mode);
    if(!infile.is_open()) {
        std::cerr << "Open " << pFilePath << " failed!" << std::endl;
        infile.close();
        return false;
    }
    while (buf && infile.get(ch)) {
        buf.put(ch);
    }
    strContent = buf.str();
    infile.close();
    return true;
}

void replace_all(std::string& str, const std::string old_value, const std::string new_value)
{
    while(true)   {
        std::string::size_type pos(0);
        if((pos=str.find(old_value))!=std::string::npos)
            str.replace(pos,old_value.length(),new_value);
        else
            break;
    }
}

/**
 * @brief ApplicationPath 返回当前EXE所在的路径
 * @return 返回路径
 */
std::string ApplicationPath() {
    char *path;
    if ((path = getcwd(NULL, 0)) == NULL) {
        std::cerr << "Get ApplicationPath Error!" << std::endl;
    }
    std::string appPath = path;
    replace_all(appPath,"\\","/");
    return appPath;
}



/**
 * @brief TrimUTF8BOM 对于带bom头的utf8字符串,删除bom头
 * @param msg 需要处理的字符串
 * @return 返回处理后的字符串
 */
std::string TrimUTF8BOM(const std::string& msg) {
    // trim utf8 bom
    std::size_t ret = msg.find_first_of("\xef\xbb\xbf");
	if(ret != std::string::npos){
		return msg.substr(3);
	}else{
        return msg;
    }
} 
